﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;
//using System.Runtime.InteropServices;
//using System.IO;
//using System.Printing;

//namespace NetPrintShare
//{
//    internal class RawPrintHelper
//    {
//        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
//        private static extern long OpenPrinter(string pPrinterName, ref IntPtr phPrinter, int pDefault);

//        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
//        private static extern long StartDocPrinter(IntPtr hPrinter, int Level, ref DOCINFO pDocInfo);

//        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
//        private static extern long StartPagePrinter(IntPtr hPrinter);

//        [DllImport("winspool.drv", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
//        private static extern long WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, ref int dwWritten);

//        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
//        private static extern long EndPagePrinter(IntPtr hPrinter);

//        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
//        private static extern long EndDocPrinter(IntPtr hPrinter);

//        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
//        private static extern long ClosePrinter(IntPtr hPrinter);

//        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
//        private struct DOCINFO
//        {
//            [MarshalAs(UnmanagedType.LPWStr)]
//            public string pDocName;
//            [MarshalAs(UnmanagedType.LPWStr)]
//            public string pOutputFile;
//            [MarshalAs(UnmanagedType.LPWStr)]
//            public string pDataType;
//        }

//        public static bool SendRawDataToPrinter(string printerName, byte[] data)
//        {
//            IntPtr printer = new IntPtr(0);
//            DOCINFO di = new DOCINFO();
//            di.pDocName = "RAW Document";
//            di.pDataType = "RAW";

//            if (OpenPrinter(printerName, ref printer, 0) != 0)
//            {
//                try
//                {
//                    Console.WriteLine("成功打开打印机");
//                    if (StartDocPrinter(printer, 1, ref di) != 0)
//                    {
//                        Console.WriteLine("成功开始打印文档");
//                        if (StartPagePrinter(printer) != 0)
//                        {
//                            Console.WriteLine("成功开始打印页面");
//                            int bytesWritten = 0;
//                            IntPtr pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length);
//                            try
//                            {
//                                Marshal.Copy(data, 0, pUnmanagedBytes, data.Length);
//                                if (WritePrinter(printer, pUnmanagedBytes, data.Length, ref bytesWritten) == 0 || bytesWritten != data.Length)
//                                {
//                                    throw new Exception("打印数据写入失败");
//                                }
//                                Console.WriteLine($"成功写入 {bytesWritten} 字节数据");
//                            }
//                            finally
//                            {
//                                Marshal.FreeCoTaskMem(pUnmanagedBytes);
//                            }
//                            if (EndPagePrinter(printer) == 0)
//                            {
//                                throw new Exception("结束打印页面失败");
//                            }
//                            Console.WriteLine("成功结束打印页面");
//                        }
//                        else
//                        {
//                            throw new Exception("开始打印页面失败");
//                        }
//                        if (EndDocPrinter(printer) == 0)
//                        {
//                            throw new Exception("结束打印文档失败");
//                        }
//                        Console.WriteLine("成功结束打印文档");
//                    }
//                    else
//                    {
//                        throw new Exception("开始打印文档失败");
//                    }
//                    Console.WriteLine($"成功使用原始方法发送数据到打印机 {printerName}");
//                    return true;
//                }
//                catch (Exception ex)
//                {
//                    Console.WriteLine($"打印过程中发生错误: {ex.Message}");
//                    return false;
//                }
//                finally
//                {
//                    ClosePrinter(printer);
//                    Console.WriteLine("关闭打印机");
//                }
//            }
//            else
//            {
//                Console.WriteLine($"无法打开打印机: {printerName}");
//                return false;
//            }
//        }
//    }
//}


using System;
using System.Runtime.InteropServices;
using System.Drawing;
using System.Drawing.Printing;
using System.IO;

namespace NetPrintShare
{
    internal class RawPrintHelper
    {
        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
        private static extern long OpenPrinter(string pPrinterName, ref IntPtr phPrinter, int pDefault);

        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = false, CallingConvention = CallingConvention.StdCall)]
        private static extern long StartDocPrinter(IntPtr hPrinter, int Level, ref DOCINFO pDocInfo);

        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern long StartPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.drv", CharSet = CharSet.Ansi, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern long WritePrinter(IntPtr hPrinter, IntPtr pBytes, int dwCount, ref int dwWritten);

        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern long EndPagePrinter(IntPtr hPrinter);

        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern long EndDocPrinter(IntPtr hPrinter);

        [DllImport("winspool.drv", CharSet = CharSet.Unicode, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
        private static extern long ClosePrinter(IntPtr hPrinter);

        [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
        private struct DOCINFO
        {
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pDocName;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pOutputFile;
            [MarshalAs(UnmanagedType.LPWStr)]
            public string pDataType;
        }

        public static bool SendRawDataToPrinter(string printerName, byte[] data)
        {
            IntPtr printer = new IntPtr(0);
            DOCINFO di = new DOCINFO();
            di.pDocName = "RAW Document";
            di.pDataType = "RAW";

            if (OpenPrinter(printerName, ref printer, 0) != 0)
            {
                try
                {
                    Console.WriteLine("成功打开打印机");
                    if (StartDocPrinter(printer, 1, ref di) != 0)
                    {
                        Console.WriteLine("成功开始打印文档");
                        if (StartPagePrinter(printer) != 0)
                        {
                            Console.WriteLine("成功开始打印页面");
                            int bytesWritten = 0;
                            IntPtr pUnmanagedBytes = Marshal.AllocCoTaskMem(data.Length);
                            try
                            {
                                Marshal.Copy(data, 0, pUnmanagedBytes, data.Length);
                                if (WritePrinter(printer, pUnmanagedBytes, data.Length, ref bytesWritten) == 0 || bytesWritten != data.Length)
                                {
                                    throw new Exception("打印数据写入失败");
                                }
                                Console.WriteLine($"成功写入 {bytesWritten} 字节数据");
                            }
                            finally
                            {
                                Marshal.FreeCoTaskMem(pUnmanagedBytes);
                            }
                            if (EndPagePrinter(printer) == 0)
                            {
                                throw new Exception("结束打印页面失败");
                            }
                            Console.WriteLine("成功结束打印页面");
                        }
                        else
                        {
                            throw new Exception("开始打印页面失败");
                        }
                        if (EndDocPrinter(printer) == 0)
                        {
                            throw new Exception("结束打印文档失败");
                        }
                        Console.WriteLine("成功结束打印文档");
                    }
                    else
                    {
                        throw new Exception("开始打印文档失败");
                    }
                    Console.WriteLine($"成功使用原始方法发送数据到打印机 {printerName}");
                    return true;
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"打印过程中发生错误: {ex.Message}");
                    return false;
                }
                finally
                {
                    ClosePrinter(printer);
                    Console.WriteLine("关闭打印机");
                }
            }
            else
            {
                Console.WriteLine($"无法打开打印机: {printerName}");
                return false;
            }
        }

        public static bool SendGDIDataToPrinter(string printerName, byte[] data)
        {
            try
            {
                PrintDocument pd = new PrintDocument();
                pd.PrinterSettings.PrinterName = printerName;
                pd.DocumentName = "GDI Document";

                pd.PrintPage += (sender, e) =>
                {
                    using (MemoryStream ms = new MemoryStream(data))
                    using (StreamReader sr = new StreamReader(ms))
                    {
                        string content = sr.ReadToEnd();
                        e.Graphics.DrawString(content, new Font("Arial", 10), Brushes.Black, new RectangleF(0, 0, e.PageBounds.Width, e.PageBounds.Height));
                    }
                };

                pd.Print();
                Console.WriteLine($"成功使用GDI方法发送数据到打印机 {printerName}");
                return true;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"GDI打印过程中发生错误: {ex.Message}");
                return false;
            }
        }

        public static bool SendDataToPrinter(string printerName, byte[] data)
        {
            if (SendRawDataToPrinter(printerName, data))
            {
                return true;
            }
            else
            {
                Console.WriteLine("尝试原始打印方法失败，正在尝试GDI打印方法...");
                return SendGDIDataToPrinter(printerName, data);
            }
        }
    }
}
